package jp.selfportrait.twonkyscrobbler4j;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.roarsoftware.lastfm.scrobble.ResponseStatus;
import net.roarsoftware.lastfm.scrobble.Scrobbler;
import net.roarsoftware.lastfm.scrobble.Source;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author kazuho
 */
public class SAXContentsHandler extends DefaultHandler {

    enum State {

        TITLE, ARTIST, ALBUM, DATETIME, DURATION, NONE
    };

    State currentState = State.NONE;
    State prevState = State.NONE;
    Music playing = new Music();
    String currentData = "";
    String prevData = "";

    @Override
    public void startElement(String uri,
            String localName,
            String qName,
            Attributes attributes) {
        if (qName.equals("title")) {
            currentState = State.TITLE;
        } else if (qName.equals("author")) {
            currentState = State.ARTIST;
        } else if (qName.equals("description")) {
            currentState = State.ALBUM;
        } else if (qName.equals("playeddatetime")) {
            currentState = State.DATETIME;
        } else if (qName.equals("duration")) {
            currentState = State.DURATION;
        }
    }

    @Override
    public void characters(char[] ch, int offset, int length) {
        currentData = new String(ch, offset, length);
        if (currentState == State.TITLE && prevState == State.TITLE) {
            prevData = playing.getTitle();
            playing.setTitle(prevData + currentData);
        } else if (currentState == State.ARTIST && prevState == State.ARTIST) {
            prevData = playing.getArtist();
            playing.setArtist(prevData + currentData);
        } else if (currentState == State.ALBUM && prevState == State.ALBUM) {
            prevData = playing.getAlbum();
            playing.setAlbum(prevData + currentData);
        } else if (currentState == State.TITLE) {
            playing.setTitle(currentData);
        } else if (currentState == State.ARTIST) {
            playing.setArtist(currentData);
        } else if (currentState == State.ALBUM) {
            playing.setAlbum(currentData);
        } else if (currentState == State.DATETIME) {
            playing.setDateTimeString(currentData);
        } else if (currentState == State.DURATION) {
            playing.setDuration(Integer.valueOf(currentData) / 1000);
        }
        prevState = currentState;
    }

    @Override
    public void endElement(String uri,
            String localName,
            String qName) {
        currentState = State.NONE;
        prevState = State.NONE;
    }

    @Override
    public void endDocument() {
        Pattern pattern;
        Matcher matcher;

        // Replace referenced character.
        // Title
        pattern = Pattern.compile("&lt;");
        matcher = pattern.matcher(playing.getTitle());
        playing.setTitle(matcher.replaceAll("<"));
        pattern = Pattern.compile("&gt;");
        matcher = pattern.matcher(playing.getTitle());
        playing.setTitle(matcher.replaceAll(">"));
        pattern = Pattern.compile("&amp;");
        matcher = pattern.matcher(playing.getTitle());
        playing.setTitle(matcher.replaceAll("&"));
        // Artist
        pattern = Pattern.compile("&lt;");
        matcher = pattern.matcher(playing.getArtist());
        playing.setArtist(matcher.replaceAll("<"));
        pattern = Pattern.compile("&gt;");
        matcher = pattern.matcher(playing.getArtist());
        playing.setArtist(matcher.replaceAll(">"));
        pattern = Pattern.compile("&amp;");
        matcher = pattern.matcher(playing.getArtist());
        playing.setArtist(matcher.replaceAll("&"));
        pattern = Pattern.compile("&quot;");
        // Album
        pattern = Pattern.compile("&lt;");
        matcher = pattern.matcher(playing.getAlbum());
        playing.setAlbum(matcher.replaceAll("<"));
        pattern = Pattern.compile("&gt;");
        matcher = pattern.matcher(playing.getAlbum());
        playing.setAlbum(matcher.replaceAll(">"));
        pattern = Pattern.compile("&amp;");
        matcher = pattern.matcher(playing.getAlbum());
        playing.setAlbum(matcher.replaceAll("&"));

        // Trim and add "The".
        String artist = playing.getArtist();
        if (artist.endsWith(", The")) {
            artist = "The " + artist.substring(0, artist.length() - 5);
            playing.setArtist(artist);
        }
        String album = playing.getAlbum();
        if (album.endsWith(", The")) {
            album = "The " + album.substring(0, album.length() - 5);
            playing.setAlbum(album);
        }

        if (TwonkyScrobbler4J.lastPlayed == null) {
             // playing
            TwonkyScrobbler4J.lastPlayed = playing;
        } else if (TwonkyScrobbler4J.lastPlayed.dateTime == null) {
            System.out.println("Skipped scrobbling.  Illegal data format.");
        } else if (playing.dateTime.compareTo(TwonkyScrobbler4J.lastPlayed.dateTime) > 0) {
            try {
                // Scrobble
                TwonkyScrobbler4J.lastPlayed = playing;
                Scrobbler scrobbler = Scrobbler.newScrobbler("tst", "1.0", TwonkyScrobbler4J.user);
                ResponseStatus status = scrobbler.handshake(TwonkyScrobbler4J.password);
                status = scrobbler.nowPlaying(
                        playing.getArtist(),
                        playing.getTitle(),
                        playing.getAlbum(),
                        playing.getDuration(),
                        -1);
                status = scrobbler.submit(
                        playing.getArtist(),
                        playing.getTitle(),
                        playing.getAlbum(),
                        playing.getDuration(),
                        -1,
                        Source.USER,
                        (System.currentTimeMillis() / 1000));
                System.out.println("Scrobbled...");
                System.out.println(playing.getArtist());
                System.out.println(playing.getTitle());
                System.out.println(playing.getAlbum());
            } catch (IOException ex) {
        }
    }
}
